﻿using System;
using dnAnalytics.Mcmc;
using dnAnalytics.Statistics.Distributions;
using NUnit.Framework;

namespace dnAnalytics.Tests.MCMC
{
    [TestFixture]
    public class MetropolisHastingsSamplerTests
    {
        [Test]
        public void MetropolisHastingsConstructor()
        {
            var normal = new Normal(0.0, 1.0);
            var rnd = new dnAnalytics.Random.MersenneTwister();

            var ms = new MetropolisHastingsSampler<double>(0.2, normal.Density, (x,y) => (new Normal(x,0.1)).Density(y),
                x => Normal.Sample(rnd, x, 0.1), 10);
            ms.RandomNumberGenerator = rnd;
            Assert.IsNotNull(ms.RandomNumberGenerator);

            ms.RandomNumberGenerator = new System.Random();
            Assert.IsNotNull(ms.RandomNumberGenerator);
        }

        [Test]
        public void SampleTest()
        {
            var normal = new Normal(0.0, 1.0);
            var rnd = new dnAnalytics.Random.MersenneTwister();

            var ms = new MetropolisHastingsSampler<double>(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y),
                x => Normal.Sample(rnd, x, 0.1), 10);
            ms.RandomNumberGenerator = rnd;

            double sample = ms.Sample();
        }

        [Test]
        public void SampleArrayTest()
        {
            var normal = new Normal(0.0, 1.0);
            var rnd = new dnAnalytics.Random.MersenneTwister();

            var ms = new MetropolisHastingsSampler<double>(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y),
                x => Normal.Sample(rnd, x, 0.1), 10);
            ms.RandomNumberGenerator = rnd;

            double[] sample = ms.Sample(5);
        }

        [Test]
        [ExpectedException(typeof(ArgumentNullException))]
        public void NullRandomNumberGenerator()
        {
            var normal = new Normal(0.0, 1.0);
            var ms = new MetropolisHastingsSampler<double>(0.2, normal.Density, (x, y) => (new Normal(x, 0.1)).Density(y),
                x => Normal.Sample(new System.Random(), x, 0.1), 10);
            ms.RandomNumberGenerator = null;
        }
    }
}
